/*!
    \file    change log.txt
    \brief   change log for GD32F20x firmware

    \version 2026-02-06, V3.0.0, firmware for GD32F20x
*/

/*
    Copyright (c) 2026, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

******************* V3.0.0 2026-02-06 ************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_misc.c
fix reason: 
Fix the error reported by misra-c 2004
V2.9.0:
void nvic_irq_disable(IRQn_Type nvic_irq)
{
    /* disable the selected IRQ.*/
    NVIC->ICER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
}

/*!
    \brief      enable NVIC interrupt request
    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
    \param[in]  nvic_irq_pre_priority: the pre-emption priority needed to set
    \param[in]  nvic_irq_sub_priority: the subpriority needed to set
    \param[out] none
    \retval     none
*/
void nvic_irq_enable(IRQn_Type nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)
{
    uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;

    /* use the priority group value to get the temp_pre and the temp_sub */
    switch((SCB->AIRCR) & (uint32_t)0x700U) {
    case NVIC_PRIGROUP_PRE0_SUB4:
        temp_pre = 0U;
        temp_sub = 0x4U;
        break;
    case NVIC_PRIGROUP_PRE1_SUB3:
        temp_pre = 1U;
        temp_sub = 0x3U;
        break;
    case NVIC_PRIGROUP_PRE2_SUB2:
        temp_pre = 2U;
        temp_sub = 0x2U;
        break;
    case NVIC_PRIGROUP_PRE3_SUB1:
        temp_pre = 3U;
        temp_sub = 0x1U;
        break;
    case NVIC_PRIGROUP_PRE4_SUB0:
        temp_pre = 4U;
        temp_sub = 0x0U;
        break;
    default:
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
        temp_pre = 2U;
        temp_sub = 0x2U;
        break;
    }

    /* get the temp_priority to fill the NVIC->IP register */
    temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
    temp_priority |= nvic_irq_sub_priority & (0x0FU >> (0x4U - temp_sub));
    temp_priority = temp_priority << 0x04U;
    NVIC->IP[nvic_irq] = (uint8_t)temp_priority;

    /* enable the selected IRQ */
    NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
}

V3.0.0:
void nvic_irq_disable(IRQn_Type nvic_irq)
{
    /* disable the selected IRQ.*/
    NVIC_DisableIRQ(nvic_irq);
}

/*!
    \brief      enable NVIC interrupt request
    \param[in]  nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
    \param[in]  nvic_irq_pre_priority: the pre-emption priority needed to set
    \param[in]  nvic_irq_sub_priority: the subpriority needed to set
    \param[out] none
    \retval     none
*/
void nvic_irq_enable(IRQn_Type nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)
{
    uint32_t nvic_prigroup, nvic_priority;

    /* check current priority group */
    switch(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) {
    case NVIC_PRIGROUP_PRE0_SUB4:
    case NVIC_PRIGROUP_PRE1_SUB3:
    case NVIC_PRIGROUP_PRE2_SUB2:
    case NVIC_PRIGROUP_PRE3_SUB1:
    case NVIC_PRIGROUP_PRE4_SUB0:
        break;
    default:
        nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
        break;
    }

    /* get the priority group value */
    nvic_prigroup = NVIC_GetPriorityGrouping();

    /* encoding the pre-emption, subpriority priority */
    nvic_priority = NVIC_EncodePriority(nvic_prigroup, (uint32_t)nvic_irq_pre_priority, (uint32_t)nvic_irq_sub_priority);
    /* set priority */
    NVIC_SetPriority(nvic_irq, nvic_priority);

    /* enable the selected IRQ */
    NVIC_EnableIRQ(nvic_irq);
}
__________________________________________________________________________________________________________________________

_____________________ ADC ________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________BKP_________________________________________________________________________________________________
Fix file:
../Examples/BKP/Backup_data/main.c
fix reason: 
Detailed Description confirm RCU_BDCTL_BKPRST bit is reset
V2.9.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* led configuration and turn on all led */
    led_config();
    /* PMU lock enable */
    rcu_periph_clock_enable(RCU_PMU);
    /* BKP clock enable */
    rcu_periph_clock_enable(RCU_BKPI);
    /* enable write access to the registers in backup domain */
    pmu_backup_write_enable();
    /* clear the bit flag of tamper event */
    bkp_flag_clear(BKP_FLAG_TAMPER0);

    /* check if the POR/PDR reset flag is set */
    if(RESET != rcu_flag_get(RCU_FLAG_PORRST)) {
        /* clear the RCU all reset flags */
        rcu_all_reset_flag_clear();
        /* turn on LED3 */
        gd_eval_led_on(LED3);

        /* check if backup data registers has been written */
        if(0x00 == check_backup_register(0x1226)) {
            /* Backup data registers values are correct */
            /* turn on LED1 */
            gd_eval_led_on(LED1);
        } else {
            /* backup data registers values are not correct or they are not written*/
            /* write data to backup data registers */
            write_backup_register(0x1226);
            /* turn on LED2 */
            gd_eval_led_on(LED2);
        }
    }
    /* turn on LED4 */
    gd_eval_led_on(LED4);
    while(1) {
    }
}

V3.0.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* led configuration and turn on all led */
    led_config();
    /* PMU lock enable */
    rcu_periph_clock_enable(RCU_PMU);
    /* BKP clock enable */
    rcu_periph_clock_enable(RCU_BKPI);
    /* enable write access to the registers in backup domain */
    pmu_backup_write_enable();
    /* confirm RCU_BDCTL_BKPRST bit is reset */
    if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)){
       rcu_bkp_reset_disable();
    }
    /* clear the bit flag of tamper event */
    bkp_flag_clear(BKP_FLAG_TAMPER0);

    /* check if the POR/PDR reset flag is set */
    if(RESET != rcu_flag_get(RCU_FLAG_PORRST)) {
        /* clear the RCU all reset flags */
        rcu_all_reset_flag_clear();
        /* turn on LED3 */
        gd_eval_led_on(LED3);

        /* check if backup data registers has been written */
        if(0x00 == check_backup_register(0x1226)) {
            /* Backup data registers values are correct */
            /* turn on LED1 */
            gd_eval_led_on(LED1);
        } else {
            /* backup data registers values are not correct or they are not written*/
            /* write data to backup data registers */
            write_backup_register(0x1226);
            /* turn on LED2 */
            gd_eval_led_on(LED2);
        }
    }
    /* turn on LED4 */
    gd_eval_led_on(LED4);
    while(1) {
    }
}
__________________________________________________________________________________________________________________________

______________________CAN_________________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_standard_peripheral/Include/gd32f20x_can.h
fix reason: 
CAN filter base address modify（CAN filter 23 data 0 register/ CAN filter 17 data 1 register）
V2.9.0:
#define CAN_F23DATA0(canx)                 REG32((canx) + 0x000003F8U)        /*!< CAN filter 23 data 0 register */
#define CAN_F17DATA1(canx)                 REG32((canx) + 0x0000024CU)        /*!< CAN filter 17 data 1 register */

V3.0.0:
#define CAN_F23DATA0(canx)                 REG32((canx) + 0x000002F8U)        /*!< CAN filter 23 data 0 register */
#define CAN_F17DATA1(canx)                 REG32((canx) + 0x000002CCU)        /*!< CAN filter 17 data 1 register */

__________________________________________________________________________________________________________________________

______________________CAU_________________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_aes.c
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_des.c
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_tdes.c
fix reason: 
Fix the error reported by misra-c 2004
V2.9.0:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_aes.c
/*!
    \brief      encrypt and decrypt using AES in ECB mode
    \param[in]  algo_dir: algorithm direction
                only one parameter can be selected which is shown as below
      \arg        CAU_ENCRYPT: encrypt
      \arg        CAU_DECRYPT: decrypt
    \param[in]  key: key used for AES algorithm
    \param[in]  keysize: length of the key, must be a 128, 192 or 256
    \param[in]  text: pointer to the text information struct
                  input: pointer to the input buffer
                  in_length: length of the input buffer, must be a multiple of 16
                  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
ErrStatus cau_aes_ecb(uint32_t algo_dir, uint8_t *key, uint16_t keysize, cau_text_struct *text)
{
    ErrStatus ret = ERROR;
    cau_key_parameter_struct key_initpara;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    /* key structure initialization */
    cau_key_parameter_init(&key_initpara);
    /* AES key structure parameter config */
    cau_aes_key_config(key, keysize, &key_initpara);
    /* key initialization */
    cau_key_init(&key_initpara);

    /* AES decryption */
    if(CAU_DECRYPT == algo_dir) {
        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();
        /* initialize the CAU peripheral */
        cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);

        /* enable the CAU peripheral */
        cau_enable();

        /* wait until the busy flag is RESET */
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            return ERROR;
        }
    }

    /* initialize the CAU peripheral */
    cau_init(algo_dir, CAU_MODE_AES_ECB, CAU_SWAPPING_8BIT);

    /* flush the IN and OUT FIFOs */
    cau_fifo_flush();

    /* enable the CAU peripheral */
    cau_enable();
    /* AES calculate process */
    ret = cau_aes_calculate(text->input, text->in_length, text->output);
    /* disable the CAU peripheral */
    cau_disable();

    return ret;
}

/*!
    \brief      encrypt and decrypt using AES in CBC mode
    \param[in]  algo_dir: algorithm direction
                only one parameter can be selected which is shown as below
      \arg        CAU_ENCRYPT: encrypt
      \arg        CAU_DECRYPT: decrypt
    \param[in]  key: key used for AES algorithm
    \param[in]  keysize: length of the key, must be a 128, 192 or 256
    \param[in]  iv: initialization vectors used for TDES algorithm
    \param[in]  text: pointer to the text information struct
                  input: pointer to the input buffer
                  in_length: length of the input buffer, must be a multiple of 16
                  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
ErrStatus cau_aes_cbc(uint32_t algo_dir, uint8_t *key, uint16_t keysize, uint8_t iv[16], cau_text_struct *text)
{
    ErrStatus ret = ERROR;
    cau_key_parameter_struct key_initpara;
    cau_iv_parameter_struct iv_initpara;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    uint32_t ivaddr = (uint32_t)iv;

    /* key structure initialization */
    cau_key_parameter_init(&key_initpara);
    /* AES key structure parameter config */
    cau_aes_key_config(key, keysize, &key_initpara);
    /* key initialization */
    cau_key_init(&key_initpara);

    /* AES decryption */
    if(CAU_DECRYPT == algo_dir) {
        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();
        /* initialize the CAU peripheral */
        cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);

        /* enable the CAU peripheral */
        cau_enable();

        /* wait until the busy flag is RESET */
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            return ERROR;
        }
    }

    /* initialize the CAU peripheral */
    cau_init(algo_dir, CAU_MODE_AES_CBC, CAU_SWAPPING_8BIT);

    /* vectors initialization */
    iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
    ivaddr += 4U;
    iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
    ivaddr += 4U;
    iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
    ivaddr += 4U;
    iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
    cau_iv_init(&iv_initpara);

    /* flush the IN and OUT FIFOs */
    cau_fifo_flush();

    /* enable the CAU peripheral */
    cau_enable();
    /* AES calculate process */
    ret = cau_aes_calculate(text->input, text->in_length, text->output);
    /* disable the CAU peripheral */
    cau_disable();

    return ret;
}

../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_des.c
/*!
    \brief      DES calculate process
    \param[in]  input: pointer to the input buffer
    \param[in]  in_length: length of the input buffer, must be a multiple of 8
    \param[in]  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
{
    uint32_t inputaddr  = (uint32_t)input;
    uint32_t outputaddr = (uint32_t)output;
    uint32_t i = 0U;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    /* the clock is not enabled or there is no embeded CAU peripheral */
    if(DISABLE == cau_enable_state_get()) {
        return ERROR;
    }

    for(i = 0U; i < in_length; i += 8U) {
        /* write data to the IN FIFO */
        cau_data_write(*(uint32_t *)(inputaddr));
        inputaddr += 4U;
        cau_data_write(*(uint32_t *)(inputaddr));
        inputaddr += 4U;

        /* wait until the complete message has been processed */
        counter = 0U;
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((DESBUSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            return ERROR;
        } else {
            /* read the output block from the output FIFO */
            *(uint32_t *)(outputaddr) = cau_data_read();
            outputaddr += 4U;
            *(uint32_t *)(outputaddr) = cau_data_read();
            outputaddr += 4U;
        }
    }

    return SUCCESS;
}

../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_tdes.c
/*!
    \brief      TDES calculate process
    \param[in]  input: pointer to the input buffer
    \param[in]  in_length: length of the input buffer, must be a multiple of 8
    \param[in]  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
{
    uint32_t inputaddr  = (uint32_t)input;
    uint32_t outputaddr = (uint32_t)output;
    uint32_t i = 0U;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    /* the clock is not enabled or there is no embedded CAU peripheral */
    if(DISABLE == cau_enable_state_get()) {
        return ERROR;
    }

    for(i = 0U; i < in_length; i += 8U) {
        /* write data to the IN FIFO */
        cau_data_write(*(uint32_t *)(inputaddr));
        inputaddr += 4U;
        cau_data_write(*(uint32_t *)(inputaddr));
        inputaddr += 4U;

        /* wait until the complete message has been processed */
        counter = 0U;
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((TDESBSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            return ERROR;
        } else {
            /* read the output block from the output FIFO */
            *(uint32_t *)(outputaddr) = cau_data_read();
            outputaddr += 4U;
            *(uint32_t *)(outputaddr) = cau_data_read();
            outputaddr += 4U;
        }
    }

    return SUCCESS;
}

V3.0.0:
/*!
    \brief      encrypt and decrypt using AES in ECB mode
    \param[in]  algo_dir: algorithm direction
                only one parameter can be selected which is shown as below
      \arg        CAU_ENCRYPT: encrypt
      \arg        CAU_DECRYPT: decrypt
    \param[in]  key: key used for AES algorithm
    \param[in]  keysize: length of the key, must be a 128, 192 or 256
    \param[in]  text: pointer to the text information struct
                  input: pointer to the input buffer
                  in_length: length of the input buffer, must be a multiple of 16
                  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
ErrStatus cau_aes_ecb(uint32_t algo_dir, uint8_t *key, uint16_t keysize, cau_text_struct *text)
{
    ErrStatus ret = SUCCESS;
    cau_key_parameter_struct key_initpara;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    /* key structure initialization */
    cau_key_parameter_init(&key_initpara);
    /* AES key structure parameter config */
    cau_aes_key_config(key, keysize, &key_initpara);
    /* key initialization */
    cau_key_init(&key_initpara);

    /* AES decryption */
    if(CAU_DECRYPT == algo_dir) {
        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();
        /* initialize the CAU peripheral */
        cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);

        /* enable the CAU peripheral */
        cau_enable();

        /* wait until the busy flag is RESET */
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            ret = ERROR;
        }
    }

    if(ret == SUCCESS) {
        /* initialize the CAU peripheral */
        cau_init(algo_dir, CAU_MODE_AES_ECB, CAU_SWAPPING_8BIT);
        
        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();
        
        /* enable the CAU peripheral */
        cau_enable();
        /* AES calculate process */
        ret = cau_aes_calculate(text->input, text->in_length, text->output);
        /* disable the CAU peripheral */
        cau_disable();
    }

    return ret;
}

/*!
    \brief      encrypt and decrypt using AES in CBC mode
    \param[in]  algo_dir: algorithm direction
                only one parameter can be selected which is shown as below
      \arg        CAU_ENCRYPT: encrypt
      \arg        CAU_DECRYPT: decrypt
    \param[in]  key: key used for AES algorithm
    \param[in]  keysize: length of the key, must be a 128, 192 or 256
    \param[in]  iv: initialization vectors used for TDES algorithm
    \param[in]  text: pointer to the text information struct
                  input: pointer to the input buffer
                  in_length: length of the input buffer, must be a multiple of 16
                  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
ErrStatus cau_aes_cbc(uint32_t algo_dir, uint8_t *key, uint16_t keysize, uint8_t iv[16], cau_text_struct *text)
{
    ErrStatus ret = SUCCESS;
    cau_key_parameter_struct key_initpara;
    cau_iv_parameter_struct iv_initpara;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;

    uint32_t ivaddr = (uint32_t)iv;

    /* key structure initialization */
    cau_key_parameter_init(&key_initpara);
    /* AES key structure parameter config */
    cau_aes_key_config(key, keysize, &key_initpara);
    /* key initialization */
    cau_key_init(&key_initpara);

    /* AES decryption */
    if(CAU_DECRYPT == algo_dir) {
        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();
        /* initialize the CAU peripheral */
        cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);

        /* enable the CAU peripheral */
        cau_enable();

        /* wait until the busy flag is RESET */
        do {
            busystatus = cau_flag_get(CAU_FLAG_BUSY);
            counter++;
        } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));

        if(RESET != busystatus) {
            ret = ERROR;
        }
    }

    if(ret == SUCCESS) {
        /* initialize the CAU peripheral */
        cau_init(algo_dir, CAU_MODE_AES_CBC, CAU_SWAPPING_8BIT);

        /* vectors initialization */
        iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
        ivaddr += 4U;
        iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
        ivaddr += 4U;
        iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
        ivaddr += 4U;
        iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
        cau_iv_init(&iv_initpara);

        /* flush the IN and OUT FIFOs */
        cau_fifo_flush();

        /* enable the CAU peripheral */
        cau_enable();
        /* AES calculate process */
        ret = cau_aes_calculate(text->input, text->in_length, text->output);
        /* disable the CAU peripheral */
        cau_disable();
    }

    return ret;
}

../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_des.c
/*!
    \brief      DES calculate process
    \param[in]  input: pointer to the input buffer
    \param[in]  in_length: length of the input buffer, must be a multiple of 8
    \param[in]  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
{
    uint32_t inputaddr  = (uint32_t)input;
    uint32_t outputaddr = (uint32_t)output;
    uint32_t i = 0U;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;
    ErrStatus status = SUCCESS;

    /* the clock is not enabled or there is no embeded CAU peripheral */
    if(DISABLE == cau_enable_state_get()) {
        status = ERROR;
    } else {
        for(i = 0U; i < in_length; i += 8U) {
            /* write data to the IN FIFO */
            cau_data_write(*(uint32_t *)(inputaddr));
            inputaddr += 4U;
            cau_data_write(*(uint32_t *)(inputaddr));
            inputaddr += 4U;

            /* wait until the complete message has been processed */
            counter = 0U;
            do {
                busystatus = cau_flag_get(CAU_FLAG_BUSY);
                counter++;
            } while((DESBUSY_TIMEOUT != counter) && (RESET != busystatus));

            if(RESET != busystatus) {
                status = ERROR;
                break;
            } else {
                /* read the output block from the output FIFO */
                *(uint32_t *)(outputaddr) = cau_data_read();
                outputaddr += 4U;
                *(uint32_t *)(outputaddr) = cau_data_read();
                outputaddr += 4U;
            }
        }
    }
    return status;
}

../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_cau_tdes.c
/*!
    \brief      TDES calculate process
    \param[in]  input: pointer to the input buffer
    \param[in]  in_length: length of the input buffer, must be a multiple of 8
    \param[in]  output: pointer to the returned buffer
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
    \note       This function contain scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
{
    uint32_t inputaddr  = (uint32_t)input;
    uint32_t outputaddr = (uint32_t)output;
    uint32_t i = 0U;
    __IO uint32_t counter = 0U;
    uint32_t busystatus = 0U;
    ErrStatus status = SUCCESS;

    /* the clock is not enabled or there is no embedded CAU peripheral */
    if(DISABLE == cau_enable_state_get()) {
        status = ERROR;
    } else {
        for(i = 0U; i < in_length; i += 8U) {
            /* write data to the IN FIFO */
            cau_data_write(*(uint32_t *)(inputaddr));
            inputaddr += 4U;
            cau_data_write(*(uint32_t *)(inputaddr));
            inputaddr += 4U;
    
            /* wait until the complete message has been processed */
            counter = 0U;
            do {
                busystatus = cau_flag_get(CAU_FLAG_BUSY);
                counter++;
            } while((TDESBSY_TIMEOUT != counter) && (RESET != busystatus));
    
            if(RESET != busystatus) {
                status = ERROR;
                break;
            } else {
                /* read the output block from the output FIFO */
                *(uint32_t *)(outputaddr) = cau_data_read();
                outputaddr += 4U;
                *(uint32_t *)(outputaddr) = cau_data_read();
                outputaddr += 4U;
            }
        }
    }
    return status;
}
__________________________________________________________________________________________________________________________

______________________CRC_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________DAC_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________DBG_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________DCI_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________DMA_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________ENET________________________________________________________________________________________________
Fix file:
../Examples/ENET/Telnet
fix reason: 
upgrade lwip version to 2.2.1
__________________________________________________________________________________________________________________________

______________________EXMC________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________EXTI________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________FMC_________________________________________________________________________________________________
Fix file:
../Examples/FMC/Erase_program/main.c
fix reason: 
Add flag clear operation before all flash operations
V2.9.0:
/*!
    \brief      erase FMC pages from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_erase_pages(void)
{
    uint32_t erase_counter;

    /* unlock the flash program/erase controller */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

    /* erase the flash pages */
    for(erase_counter = 0; erase_counter < page_num; erase_counter++) {
        fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * erase_counter));
        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    }

    /* lock the main FMC after the erase operation */
    fmc_lock();
}

/*!
    \brief      program FMC word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_program(void)
{
    /* unlock the flash program/erase controller */
    fmc_unlock();

    address = FMC_WRITE_START_ADDR;

    /* program flash */
    while(address < FMC_WRITE_END_ADDR) {
        fmc_word_program(address, data0);
        address += 4;
        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    }

    /* lock the main FMC after the program operation */
    fmc_lock();
}

V3.0.0:
/* clear all pending flags */
void fmc_flags_clear(void);
    
/*!
    \brief      erase FMC pages from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_erase_pages(void)
{
    uint32_t erase_counter;

    /* unlock the flash program/erase controller */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flags_clear();

    /* erase the flash pages */
    for(erase_counter = 0; erase_counter < page_num; erase_counter++) {
        fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * erase_counter));
        fmc_flags_clear();
    }

    /* lock the main FMC after the erase operation */
    fmc_lock();
}

/*!
    \brief      program FMC word by word from FMC_WRITE_START_ADDR to FMC_WRITE_END_ADDR
    \param[in]  none
    \param[out] none
    \retval     none
*/
void fmc_program(void)
{
    /* unlock the flash program/erase controller */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flags_clear();

    address = FMC_WRITE_START_ADDR;

    /* program flash */
    while(address < FMC_WRITE_END_ADDR) {
        fmc_word_program(address, data0);
        address += 4;
        fmc_flags_clear();
    }

    /* lock the main FMC after the program operation */
    fmc_lock();
}
__________________________________________________________________________________________________________________________

______________________FWDGT_______________________________________________________________________________________________
Fix file:
../Examples/FWDGT/FWDGT_key/main.c
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_fwdgt.c
fix reason: 
The implementation modifications of the functions fwdgt_prescaler_value_config, fwdgt_reload_value_config, fwdgt_config, and fwdgt_flag_get
V2.9.0:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_fwdgt.c
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status = RESET;
  
    /* enable write access to FWDGT_PSC */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
  
    /* wait until the PUD flag to be reset */
    do{
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
    
    if ((uint32_t)RESET != flag_status){
        return ERROR;
    }
    
    /* configure FWDGT */
    FWDGT_PSC = (uint32_t)prescaler_value; 

    return SUCCESS;
}

ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
{
    uint32_t timeout = FWDGT_RLD_TIMEOUT;
    uint32_t flag_status = RESET;
  
    /* enable write access to FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
  
    /* wait until the RUD flag to be reset */
    do{
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
   
    if ((uint32_t)RESET != flag_status){
        return ERROR;
    }
    
    FWDGT_RLD = RLD_RLD(reload_value);

    return SUCCESS;
}

ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status = RESET;

    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    /* configure FWDGT */
    FWDGT_PSC = (uint32_t)prescaler_div;

    timeout = FWDGT_RLD_TIMEOUT;
    /* wait until the RUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    } while((--timeout > 0U) && ((uint32_t)RESET != flag_status));

    if((uint32_t)RESET != flag_status) {
        return ERROR;
    }

    FWDGT_RLD = RLD_RLD(reload_value);

    /* reload the counter */
    FWDGT_CTL = FWDGT_KEY_RELOAD;

    return SUCCESS;
}

FlagStatus fwdgt_flag_get(uint16_t flag)
{
    if(FWDGT_STAT & flag) {
        return SET;
    }

    return RESET;
}

../Examples/FWDGT/FWDGT_key/main.c
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* configure systick  */
    systick_config();

    /* configure LED  */
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* configure the Tamper key which is used to reload FWDGT  */
    gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI);

    delay_1ms(500);

    /* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(2 * 500, FWDGT_PSC_DIV64);

    /* after 1.6 seconds to generate a reset */
    fwdgt_enable();

    /* check if the system has resumed from FWDGT reset */
    if(RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)) {
        /* turn on LED3 */
        gd_eval_led_on(LED3);
        /* clear the FWDGT reset flag */
        rcu_all_reset_flag_clear();

        while(1) {
        }

    } else {
        /* turn on LED2 */
        gd_eval_led_on(LED2);
    }

    while(1) {
    }
}

V3.0.0:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_fwdgt.c
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;
  
    /* enable write access to FWDGT_PSC */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_PSC */
    FWDGT_PSC = (uint32_t)prescaler_value;

    /* wait until the PUD flag to be reset */
    do{
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    }while((--timeout > 0U) && (0U != flag_status));
    
    if (0U != flag_status){
        status = ERROR;
    }

    return status;
}

ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
{
    uint32_t timeout = FWDGT_RLD_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;

    /* enable write access to FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_RLD */
    FWDGT_RLD = RLD_RLD(reload_value);

    /* wait until the RUD flag to be reset */
    do{
        flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
    }while((--timeout > 0U) && (0U != flag_status));
   
    if (0U != flag_status){
        status = ERROR;
    }

    return status;
}

ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_value)
{
    uint32_t timeout = FWDGT_PSC_TIMEOUT;
    uint32_t flag_status;
    ErrStatus status = SUCCESS;

    /* start the free watchdog timer counter */
    FWDGT_CTL = FWDGT_KEY_ENABLE;

    /* enable write access to FWDGT_PSC,and FWDGT_RLD */
    FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;

    /* configure FWDGT_PSC */
    FWDGT_PSC = (uint32_t)prescaler_value;

    /* wait until the PUD flag to be reset */
    do {
        flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
    } while((--timeout > 0U) && (0U != flag_status));

    if(0U != flag_status) {
        status = ERROR;
    }

    if(SUCCESS == status) {
        /* configure FWDGT_RLD */
        FWDGT_RLD = RLD_RLD(reload_value);

        /* wait until the RUD flag to be reset */
        timeout = FWDGT_RLD_TIMEOUT;
        do {
            flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
        } while((--timeout > 0U) && (0U != flag_status));

        if(0U != flag_status) {
            status = ERROR;
        }
    }

    if(SUCCESS == status) {
        /* reload the counter */
        FWDGT_CTL = FWDGT_KEY_RELOAD;
    }

    return status;
}

FlagStatus fwdgt_flag_get(uint16_t flag)
{
    FlagStatus flag_status = RESET;
    if(RESET != (FWDGT_STAT & flag)) {
        flag_status = SET;
    }
    return flag_status;
}

../Examples/FWDGT/FWDGT_key/main.c
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* configure systick  */
    systick_config();

    /* configure LED  */
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* configure the Tamper key which is used to reload FWDGT  */
    gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI);

    delay_1ms(500);

    /* configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(2 * 500, FWDGT_PSC_DIV64);

    /* check if the system has resumed from FWDGT reset */
    if(RESET != rcu_flag_get(RCU_FLAG_FWDGTRST)) {
        /* turn on LED3 */
        gd_eval_led_on(LED3);
        /* clear the FWDGT reset flag */
        rcu_all_reset_flag_clear();

        while(1) {
        }

    } else {
        /* turn on LED2 */
        gd_eval_led_on(LED2);
    }

    while(1) {
    }
}
__________________________________________________________________________________________________________________________

______________________GPIO________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________HAU_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________I2C_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________PMU_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________RCU_________________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_rcu.c
fix reason: 
Fix the error reported by misra-c 2004
V2.9.0:
/*!
    \brief      configure the PLLT clock multiplication and division factors
    \param[in]  pllt_psc: the PLLT VCO input clock division factor
      \arg        this parameter should be selected between 2 and 63. And this parameter should
                  be selected correctly to ensure that the VCO input frequency ranges from 1 to 2 MHz
    \param[in]  pllt_mul: he PLLT VCO output clock multiplication factor
      \arg        this parameter should be selected between 49 and 432
    \param[in]  ppltr_psc: the PLLTR division factor
      \arg        this parameter should be selected between 2 and 7
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
*/
ErrStatus rcu_pllt_vco_config(uint32_t pllt_psc, uint32_t pllt_mul, uint32_t ppltr_psc)
{
    uint32_t reg = 0U;

    /* check the function parameter */
    if((pllt_psc < 2U) || (pllt_psc > 63U)) {
        return ERROR;
    } else {
    }

    if((pllt_mul < 49U) || (pllt_mul > 432U)) {
        return ERROR;
    } else {
    }

    if((ppltr_psc < 2U) || (ppltr_psc > 7U)) {
        return ERROR;
    } else {
    }

    reg = RCU_PLLTCFG;

    /* reset the PLLTRPSC bits, PLLTMF bits and PLLTPSC bits */
    reg &= ~(RCU_PLLTCFG_PLLTRPSC | RCU_PLLTCFG_PLLTMF | RCU_PLLTCFG_PLLTPSC);

    reg |= (PLLTCFG_PLLTPSC(pllt_psc) | PLLTCFG_PLLTMF(pllt_mul) | PLLTCFG_PLLTRPSC(ppltr_psc));

    RCU_PLLTCFG = reg;

    return SUCCESS;
}

FlagStatus rcu_flag_get(rcu_flag_enum flag)
{
    /* get the rcu flag */
    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) {
        return SET;
    } else {
        return RESET;
    }
}

FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
{
    /* get the rcu interrupt flag */
    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) {
        return SET;
    } else {
        return RESET;
    }
}

V3.0.0:
/*!
    \brief      configure the PLLT clock multiplication and division factors
    \param[in]  pllt_psc: the PLLT VCO input clock division factor
      \arg        this parameter should be selected between 2 and 63. And this parameter should
                  be selected correctly to ensure that the VCO input frequency ranges from 1 to 2 MHz
    \param[in]  pllt_mul: he PLLT VCO output clock multiplication factor
      \arg        this parameter should be selected between 49 and 432
    \param[in]  ppltr_psc: the PLLTR division factor
      \arg        this parameter should be selected between 2 and 7
    \param[out] none
    \retval     ErrStatus: SUCCESS or ERROR
*/
ErrStatus rcu_pllt_vco_config(uint32_t pllt_psc, uint32_t pllt_mul, uint32_t ppltr_psc)
{
    uint32_t reg = 0U;
    ErrStatus status = ERROR;
    
    /* check the function parameter */
    if((pllt_psc >= 2U) && (pllt_psc <= 63U) &&
       (pllt_mul >= 49U) && (pllt_mul <= 432U) &&
       (ppltr_psc >= 2U) && (ppltr_psc <= 7U)) {

         reg = RCU_PLLTCFG;
         
         /* reset the PLLTRPSC bits, PLLTMF bits and PLLTPSC bits */
         reg &= ~(RCU_PLLTCFG_PLLTRPSC | RCU_PLLTCFG_PLLTMF | RCU_PLLTCFG_PLLTPSC);
         
         reg |= (PLLTCFG_PLLTPSC(pllt_psc) | PLLTCFG_PLLTMF(pllt_mul) | PLLTCFG_PLLTRPSC(ppltr_psc));
         
         RCU_PLLTCFG = reg;
         
         status = SUCCESS;
       }

    return status;
}

FlagStatus rcu_flag_get(rcu_flag_enum flag)
{
    FlagStatus status = RESET;
    /* get the rcu flag */
    if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) {
        status = SET;
    } else {
        status = RESET;
    }
    return status;
}

FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag)
{
    FlagStatus status = RESET;
  /* get the rcu interrupt flag */
    if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) {
        status = SET;
    } else {
        status = RESET;
    }
    return status;
}
__________________________________________________________________________________________________________________________

______________________RTC_________________________________________________________________________________________________
Fix file:
../Examples/PMU/Deepsleep_wakeup_RTC/main.c
fix reason: 
add frequency switching before going to deepsleep or standby
V2.9.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* nvic configuration */
    nvic_configuration();
    /* LED configuration */
    led_config();
    /* systick configuration */
    systick_config();
    gd_eval_led_on(LED4);
    delay_1ms(2000U);
    gd_eval_led_off(LED4);
    /* RTC configuration */
    rtc_configuration();
    /* FWDGT configuration */
    fwdgt_configuration();

    while(1){
        delay_1ms(50U);
        /* PMU enters deepsleep mode */
        pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
        gd_eval_led_toggle(LED2);
    }
}

V3.0.0:
/* software delay to prevent the impact of Vcore fluctuations.
   It is strongly recommended to include it to avoid issues caused by self-removal. */
static void _soft_delay_(uint32_t time)
{
    __IO uint32_t i;
    for(i=0; i<time*10; i++){
    }
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* nvic configuration */
    nvic_configuration();
    /* LED configuration */
    led_config();
    /* systick configuration */
    systick_config();
    gd_eval_led_on(LED4);
    delay_1ms(2000U);
    gd_eval_led_off(LED4);
    /* RTC configuration */
    rtc_configuration();
    /* FWDGT configuration */
    fwdgt_configuration();

    while(1){
        delay_1ms(50U);
        /* The following is to prevent Vcore fluctuations caused by frequency switching. 
           It is strongly recommended to include it to avoid issues caused by self-removal. */
        rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV2);
        _soft_delay_(0x50);
        rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV4);
        _soft_delay_(0x50);
        /* PMU enters deepsleep mode */
        pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
        gd_eval_led_toggle(LED2);
    }
}
__________________________________________________________________________________________________________________________

______________________SDIO________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________SYSTICK_____________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________SPI_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________TIMER_______________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________TLI_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________TRNG________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________USART_______________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________USBFS_______________________________________________________________________________________________

__________________________________________________________________________________________________________________________


******************* V2.9.0 2025-08-08 ************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
../Firmware/CMSIS/GD/GD32F20x/Source/system_gd32f20x.c
fix reason: 
update the clock switch code 
V2.8.0:
#define RCU_MODIFY(__delay)     do{                                     \
                                    volatile uint32_t i;                \
                                    if(0 != __delay){                   \
                                        RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; \
                                        for(i=0; i<__delay; i++){       \
                                        }                               \
                                        RCU_CFG0 |= RCU_AHB_CKSYS_DIV4; \
                                        for(i=0; i<__delay; i++){       \
                                        }                               \
                                    }                                   \
                                }while(0)

/*!
    \brief      setup the micro-controller system, initialize the system
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SystemInit(void)
{
    /* reset the RCC clock configuration to the default reset state */
    /* enable IRC8M */
    RCU_CTL |= RCU_CTL_IRC8MEN;
    while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
    }
    RCU_MODIFY(0x50);
    RCU_CFG0 &= ~RCU_CFG0_SCS;
    /* reset HXTALEN, CKMEN, PLLEN bits */
    RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);

    /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */
    RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |
                  RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL);

    /* reset HXTALEN, CKMEN, PLLEN bits */
    RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);

    /* Reset HXTALBPS bit */
    RCU_CTL &= ~(RCU_CTL_HXTALBPS);

    /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */
    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF |
                  RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4);

    /* reset PLL1EN and PLL2EN bits */
    RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN);

    /* reset CFG1 register */
    RCU_CFG1 = 0x00000000U;

    /* reset INT register */
    RCU_INT = 0x00FF0000U;

    /* reset CFG2 register */
    RCU_CFG2 = 0x00000000U;

    /* reset PLLTCTL register */
    RCU_PLLTCTL &= (~RCU_PLLTCTL_PLLTEN);

    /* reset PLLTINT register */
    RCU_PLLTINT = 0x00400000U;

    /* reset PLLTCFG register */
    RCU_PLLTCFG = 0x20003010U;

    /* configure the system clock source, PLL multiplier, AHB/APBx prescalers and flash settings */
    system_clock_config();
}

V2.9.0:
/* The following is to prevent Vcore fluctuations caused by frequency switching. 
   It is strongly recommended to include it to avoid issues caused by self-removal. 
*/
#define RCU_MODIFY(__delay)     do{
                                    volatile uint32_t i,reg;
                                    if(0 != __delay){
                                        reg = RCU_CFG0;
                                        reg &= ~(RCU_CFG0_AHBPSC);
                                        reg |= RCU_AHB_CKSYS_DIV2;
                                        /* CK_AHB = SYSCLK/2*/
                                        RCU_CFG0 = reg;
                                        for(i=0; i<__delay; i++){
                                        }
                                        reg = RCU_CFG0;
                                        reg &= ~(RCU_CFG0_AHBPSC);
                                        reg |= RCU_AHB_CKSYS_DIV4;
                                        /* CK_AHB = SYSCLK/4*/
                                        RCU_CFG0 = reg;
                                        for(i=0; i<__delay; i++){
                                        }
                                    }
                                }while(0)

/* software delay to prevent the impact of Vcore fluctuations.
   It is strongly recommended to include it to avoid issues caused by self-removal. */
static void _soft_delay_(uint32_t time)
{
    __IO uint32_t i;
    for(i=0; i<time*10; i++){
    }
}

/*!
    \brief      setup the micro-controller system, initialize the system
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SystemInit(void)
{
    /* reset the RCC clock configuration to the default reset state */
    /* enable IRC8M */
    RCU_CTL |= RCU_CTL_IRC8MEN;
    while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
    }
    if(((RCU_CFG0 & RCU_CFG0_SCSS) == RCU_SCSS_PLL)){
        RCU_MODIFY(0x50);
    }
    RCU_CFG0 &= ~RCU_CFG0_SCS;
    _soft_delay_(100);
    /* reset HXTALEN, CKMEN, PLLEN bits */
    RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);

    /* reset SCS, AHBPSC, APB1PSC, APB2PSC, ADCPSC, CKOUT0SEL bits */
    RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |
                  RCU_CFG0_ADCPSC | RCU_CFG0_ADCPSC_2 | RCU_CFG0_CKOUT0SEL);

    /* reset HXTALEN, CKMEN, PLLEN bits */
    RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN);

    /* Reset HXTALBPS bit */
    RCU_CTL &= ~(RCU_CTL_HXTALBPS);

    /* reset PLLSEL, PREDV0_LSB, PLLMF, USBFSPSC bits */
    RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF |
                  RCU_CFG0_USBFSPSC | RCU_CFG0_PLLMF_4);

    /* reset PLL1EN and PLL2EN bits */
    RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN);

    /* reset CFG1 register */
    RCU_CFG1 = 0x00000000U;

    /* reset INT register */
    RCU_INT = 0x00FF0000U;

    /* reset CFG2 register */
    RCU_CFG2 = 0x00000000U;

    /* reset PLLTCTL register */
    RCU_PLLTCTL &= (~RCU_PLLTCTL_PLLTEN);

    /* reset PLLTINT register */
    RCU_PLLTINT = 0x00400000U;

    /* reset PLLTCFG register */
    RCU_PLLTCFG = 0x20003010U;

    /* configure the system clock source, PLL multiplier, AHB/APBx prescalers and flash settings */
    system_clock_config();
}

Fix file:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_misc.c
../Firmware/GD32F20x_standard_peripheral/Include/gd32f20x_misc.h
fix reason: 
Modify the parameters of nvic_irq_enable/disable function
V2.8.0:
void nvic_irq_enable(uint8_t nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)

V2.9.0:
void nvic_irq_enable(IRQn_Type nvic_irq,
                     uint8_t nvic_irq_pre_priority,
                     uint8_t nvic_irq_sub_priority)
__________________________________________________________________________________________________________________________

_____________________ ADC ________________________________________________________________________________________________
Fix file:
../Examples/ADC/ADC0_software_trigger_regular_channel_polling/main.c
fix reason: 
ACD bug fix
V2.8.0:
/*!
    \brief      configure the different system clocks
    \param[in]  none
    \param[out] none
    \retval     none
*/
void rcu_config(void)
{
    /* enable GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC0);
    /* config ADC clock */
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adc_config(void)
{
    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1U);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
    /* ADC external trigger config */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable(ADC0);
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);
}

V2.9.0:
/*!
    \brief      configure the different system clocks
    \param[in]  none
    \param[out] none
    \retval     none
*/
void rcu_config(void)
{
    /* enable GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC0);
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adc_config(void)
{
    /* config ADC clock */
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
    /* ADC mode config */
    adc_mode_config(ADC_MODE_FREE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1U);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
    /* ADC external trigger config */
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable(ADC0);
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable(ADC0);
}

__________________________________________________________________________________________________________________________

______________________BKP_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________CAN_________________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_can.c
fix reason: 
can DLC bug fix
V2.8.0:
/*!
    \brief      transmit CAN message
    \param[in]  can_periph
      \arg        CANx(x=0,1)
    \param[in]  transmit_message: struct for CAN transmit message
      \arg        tx_sfid: 0x00000000 - 0x000007FF
      \arg        tx_efid: 0x00000000 - 0x1FFFFFFF
      \arg        tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
      \arg        tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
      \arg        tx_dlen: 0 - 8
      \arg        tx_data[]: 0x00 - 0xFF
    \param[out] none
    \retval     mailbox_number
*/
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message)
{
    uint8_t mailbox_number = CAN_MAILBOX0;

    /* select one empty mailbox */
    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) {
        mailbox_number = CAN_MAILBOX0;
    } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) {
        mailbox_number = CAN_MAILBOX1;
    } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) {
        mailbox_number = CAN_MAILBOX2;
    } else {
        mailbox_number = CAN_NOMAILBOX;
    }
    /* return no mailbox empty */
    if(CAN_NOMAILBOX == mailbox_number) {
        return CAN_NOMAILBOX;
    }

    CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
    if(CAN_FF_STANDARD == transmit_message->tx_ff) {
        /* set transmit mailbox standard identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
                                               transmit_message->tx_ft);
    } else {
        /* set transmit mailbox extended identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
                                               transmit_message->tx_ff | \
                                               transmit_message->tx_ft);
    }
    /* set the data length */
    CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
    CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
    /* set the data */
    CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
            TMDATA0_DB2(transmit_message->tx_data[2]) | \
            TMDATA0_DB1(transmit_message->tx_data[1]) | \
            TMDATA0_DB0(transmit_message->tx_data[0]);
    CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
            TMDATA1_DB6(transmit_message->tx_data[6]) | \
            TMDATA1_DB5(transmit_message->tx_data[5]) | \
            TMDATA1_DB4(transmit_message->tx_data[4]);
    /* enable transmission */
    CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;

    return mailbox_number;
}

V2.9.0:
/*!
    \brief      transmit CAN message
    \param[in]  can_periph
      \arg        CANx(x=0,1)
    \param[in]  transmit_message: struct for CAN transmit message
      \arg        tx_sfid: 0x00000000 - 0x000007FF
      \arg        tx_efid: 0x00000000 - 0x1FFFFFFF
      \arg        tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
      \arg        tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
      \arg        tx_dlen: 0 - 8
      \arg        tx_data[]: 0x00 - 0xFF
    \param[out] none
    \retval     mailbox_number
*/
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message)
{
    uint8_t mailbox_number = CAN_MAILBOX0;

    /* select one empty mailbox */
    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) {
        mailbox_number = CAN_MAILBOX0;
    } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) {
        mailbox_number = CAN_MAILBOX1;
    } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) {
        mailbox_number = CAN_MAILBOX2;
    } else {
        mailbox_number = CAN_NOMAILBOX;
    }
    /* return no mailbox empty */
    if(CAN_NOMAILBOX == mailbox_number) {
        return CAN_NOMAILBOX;
    }

    CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
    if(CAN_FF_STANDARD == transmit_message->tx_ff) {
        /* set transmit mailbox standard identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
                                               transmit_message->tx_ft);
    } else {
        /* set transmit mailbox extended identifier */
        CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
                                               transmit_message->tx_ff | \
                                               transmit_message->tx_ft);
    }
    /* set the data length */
    CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
    /* classic CAN frame data lenth does not exceed 8 */
    if(transmit_message->tx_dlen > 8U) {
        transmit_message->tx_dlen = 8U;
    }
    CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
    /* set the data */
    CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
            TMDATA0_DB2(transmit_message->tx_data[2]) | \
            TMDATA0_DB1(transmit_message->tx_data[1]) | \
            TMDATA0_DB0(transmit_message->tx_data[0]);
    CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
            TMDATA1_DB6(transmit_message->tx_data[6]) | \
            TMDATA1_DB5(transmit_message->tx_data[5]) | \
            TMDATA1_DB4(transmit_message->tx_data[4]);
    /* enable transmission */
    CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;

    return mailbox_number;
}



__________________________________________________________________________________________________________________________

______________________CAU_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________CRC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DAC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DBG_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DCI_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________DMA_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________ENET________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________EXMC________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________EXTI________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________FMC_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________FWDGT_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________GPIO________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________HAU_________________________________________________________________________________________________
Fix file:
/GD32F20x_Firmware_Library/Examples/HAU/Hash_SHA1_MD5/main.c
fix reason: 
example updata

V2.8.0:
uint32_t i = 0U, len = 0U;
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_com_init(EVAL_COM1);
    /* enable HAU clock */
    rcu_periph_clock_enable(RCU_HAU);

    len = sizeof(message_input);
    printf("\r\nmessage to be hashed:\r\n\r\n");
    for(i = 0U; i < len ; i++) {
        printf("%c", message_input[i]);
    }

    /* SHA-1 digest computation */
    hau_hash_sha_1((uint8_t *)message_input, len, sha1_output);
    printf(" \r\n\r\nSHA1 message digest (160 bits):\r\n\r\n");
    data_display(20U, sha1_output);

    /* MD5 digest computation */
    hau_hash_md5((uint8_t *)message_input, len, md5_output);
    printf(" \r\n\r\nMD5 message digest (128 bits):\r\n\r\n");
    data_display(16U, md5_output);

    while(1) {
    }
}

/*!
    \brief      printf data in bytes
    \param[in]  datalength: length of the data to display
    \param[in]  data: pointer to the data to display
    \param[out] none
    \retval     none
*/
static void data_display(uint32_t datalength, uint8_t *data)
{
    uint32_t i = 0U, count = 0U;

    for(i = 0U; i < datalength; i++) {
        printf("0x%02X ", data[i]);
        count++;

        if(4U == count) {
            count = 0U;
            printf("\r\n");
        }
    }
}

V2.9.0:
/* check data in bytes */
static void data_check(uint8_t *src, uint8_t *dst, uint32_t len);

__IO uint8_t check_flag = 0;

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    uint32_t i = 0;
    uint32_t len = 0;

    gd_eval_led_init(LED1);
    gd_eval_com_init(EVAL_COM1);
    /* enable HAU clock */
    rcu_periph_clock_enable(RCU_HAU);

    len = sizeof(message_input);
    printf("\r\nmessage to be hashed:\r\n\r\n");
    for(i = 0; i < len ; i++){
        printf("%c", message_input[i]);
    }

    /* SHA-1 digest computation */
    hau_hash_sha_1((uint8_t *)message_input, len, sha1_output);
    printf("  \r\n\r\nSHA1 message digest (160 bits):\r\n\r\n");
    data_display(20, sha1_output);
    data_check((uint8_t *)&sha1_output[0], (uint8_t *)&expected_data_sha1[0], 20U);

    /* MD5 digest computation */
    hau_hash_md5((uint8_t *)message_input, len, md5_output);
    printf("  \r\n\r\nMD5 message digest (128 bits):\r\n\r\n");
    data_display(16, md5_output);
    data_check((uint8_t *)&md5_output[0], (uint8_t *)&expected_data_md5[0], 16U);

    if(0U == check_flag) {
        gd_eval_led_on(LED1);
    }

    while(1) {
    }
}

/*!
    \brief      printf data in bytes
    \param[in]  datalength: length of the data to display
    \param[in]  data: pointer to the data to display
    \param[out] none
    \retval     none
*/
static void data_display(uint32_t datalength, uint8_t *data)
{
    uint32_t i =0U;
    uint32_t count = 0U;

    for(i = 0; i < datalength; i++){
        printf(" 0x%02X", data[i]);
        count++;

        if(4U == count){
            count = 0U;
            printf("\r\n");
        }
    }
}

/*!
    \brief      check data in bytes
    \param[in]  src: source
    \param[in]  dst: destination
    \param[in]  len: length of the data to check
    \param[out] none
    \retval     none
*/
static void data_check(uint8_t *src, uint8_t *dst, uint32_t len)
{
    if(memcmp((const void*)src, (const void*)dst, len) != 0){
        check_flag++;
    }
}

Fix file:
/GD32F20x_Firmware_Library/Examples/HAU/Hmac_SHA1_MD5/main.c
fix reason:
example updata
V2.8.0:
uint32_t i = 0U, meg_len = 0U, key_len = 0U;

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_com_init(EVAL_COM1);
    /* enable HAU clock */
    rcu_periph_clock_enable(RCU_HAU);

    meg_len = sizeof(message_input);
    key_len = sizeof(key);
    printf(" \r\nmessage to be hashed:\r\n\r\n");
    for(i = 0U; i < meg_len ; i++) {
        printf("%c", message_input[i]);
    }

    /* HMAC SHA-1 digest computation */
    hau_hmac_sha_1((uint8_t *)key, key_len, (uint8_t *)message_input, meg_len, sha1_output);
    printf(" \r\n\r\nSHA1 message digest (160 bits):\r\n\r\n");
    data_display(20U, sha1_output);

    /* HMAC MD5 digest computation */
    hau_hmac_md5((uint8_t *)key, key_len, (uint8_t *)message_input, meg_len, md5_output);
    printf(" \r\n\r\nMD5 Message Digest (128 bits):\r\n\r\n");
    data_display(16U, md5_output);

    while(1) {
    }
}

/*!
    \brief      printf data in bytes
    \param[in]  datalength: length of the data to display
    \param[in]  data: pointer to the data to display
    \param[out] none
    \retval     none
*/
static void data_display(uint32_t datalength, uint8_t *data)
{
    uint32_t i = 0U, count = 0U;

    for(i = 0U; i < datalength; i++) {
        printf("0x%02X ", data[i]);
        count++;

        if(4U == count) {
            count = 0U;
            printf("\r\n");
        }
    }
}
V2.9.0:
__IO uint8_t check_flag = 0;

/* printf data in bytes */
static void data_display(uint32_t datalength, uint8_t *data);
/* check data in bytes */
static void data_check(uint8_t *src, uint8_t *dst, uint32_t len);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    uint32_t i = 0, meg_len = 0, key_len = 0;

    gd_eval_led_init(LED1);
    gd_eval_com_init(EVAL_COM1);
    /* enable HAU clock */
    rcu_periph_clock_enable(RCU_HAU);

    meg_len = sizeof(message_input);
    key_len = sizeof(key);

    printf("\r\n\r\n message input:\r\n\r\n");
    for(i = 0; i < meg_len ; i++){
        printf("%c", message_input[i]);
    }
    
    printf("\r\n\r\n key input:\r\n\r\n");
    for(i = 0; i < key_len ; i++){
        printf("%c", key[i]);
    }

    /* HMAC SHA-1 digest computation */
    hau_hmac_sha_1((uint8_t *)key, key_len, (uint8_t *)message_input, meg_len, sha1_output);
    printf(" \r\n\r\nSHA1 message digest (160 bits):\r\n\r\n");
    data_display(20, sha1_output);
    data_check((uint8_t *)&sha1_output[0], (uint8_t *)&expected_data_sha1[0], 20U);

    /* HMAC MD5 digest computation */
    hau_hmac_md5((uint8_t *)key, key_len, (uint8_t *)message_input, meg_len, md5_output);
    printf(" \r\n\r\nMD5 Message Digest (128 bits):\r\n\r\n");
    data_display(16, md5_output);
    data_check((uint8_t *)&md5_output[0], (uint8_t *)&expected_data_md5[0], 16U);

    if(0U == check_flag) {
        gd_eval_led_on(LED1);
    }

    while(1) {
    }
}

/*!
    \brief      printf data in bytes
    \param[in]  datalength: length of the data to display
    \param[in]  data: pointer to the data to display
    \param[out] none
    \retval     none
*/
static void data_display(uint32_t datalength, uint8_t *data)
{
    uint32_t i = 0, count = 0;

    for(i = 0; i < datalength; i++) {
        printf(" 0x%02X", data[i]);
        count++;

        if(4U == count) {
            count = 0;
            printf("\r\n");
        }
    }
}

/*!
    \brief      check data in bytes
    \param[in]  src: source
    \param[in]  dst: destination
    \param[in]  len: length of the data to check
    \param[out] none
    \retval     none
*/
static void data_check(uint8_t *src, uint8_t *dst, uint32_t len)
{
    if(memcmp((const void*)src, (const void*)dst, len) != 0) {
        check_flag++;
    }
}
__________________________________________________________________________________________________________________________

______________________I2C_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________PMU_________________________________________________________________________________________________
Fix file:
GD32F20x_Firmware_Library/Firmware/GD32F20x_standard_peripheral/Source/gd32f20x_pmu.c
fix reason: 
Modify the implementation method for entering sleep mode
V2.8.0:
/*!
    \brief      PMU work in sleep mode
    \param[in]  sleepmodecmd:
                only one parameter can be selected which is shown as below:
      \arg        WFI_CMD: use WFI command
      \arg        WFE_CMD: use WFE command
    \param[out] none
    \retval     none
*/
void pmu_to_sleepmode(uint8_t sleepmodecmd)
{
    /* clear sleepdeep bit of Cortex-M3 system control register */
    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);

    /* select WFI or WFE command to enter sleep mode */
    if(WFI_CMD == sleepmodecmd) {
        __WFI();
    } else {
        __WFE();
    }
}

V2.9.0:
/*!
    \brief      PMU work in sleep mode
    \param[in]  sleepmodecmd:
                only one parameter can be selected which is shown as below:
      \arg        WFI_CMD: use WFI command
      \arg        WFE_CMD: use WFE command
    \param[out] none
    \retval     none
*/
void pmu_to_sleepmode(uint8_t sleepmodecmd)
{
    /* clear sleepdeep bit of Cortex-M3 system control register */
    SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);

    /* select WFI or WFE command to enter sleep mode */
    if(WFI_CMD == sleepmodecmd) {
        __WFI();
    } else {
        __SEV();
        __WFE();
        __WFE();
    }
}

__________________________________________________________________________________________________________________________

______________________RCU_________________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________RTC_________________________________________________________________________________________________
Fix file:
../Examples/RTC/Calendar_demo/main.c"
fix reason: 
If RCU_BDCTL_BKPRST is set, reading BKP_DATAx will cause the MCU to crash. Therefore, before reading BKP_DATAx, check whether RCU_BDCTL_BKPRST is set. If it is set, clear it first.
V2.8.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* COM1 config */
    gd_eval_com_init(EVAL_COM1);

    /* NVIC config */
    nvic_configuration();

    printf("\r\n This is a RTC demo...... \r\n");

    if(0xA5A5 != bkp_data_read(BKP_DATA_0)) {
        /* backup data register value is not correct or not yet programmed
        (when the first time the program is executed) */
        printf("\r\nThis is a RTC demo!\r\n");
        printf("\r\n\n RTC not yet configured....");

        /* RTC configuration */
        rtc_config();

        /* adjust time by values entred by the user on the hyperterminal */
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
        /* change the current time */
        rtc_counter_set(time_regulate());
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();

        bkp_data_write(BKP_DATA_0, 0xA5A5);
    } else {
        /* check if the power on reset flag is set */
        if(RESET != rcu_flag_get(RCU_FLAG_SWRST)) {
            /* check if the pin reset flag is set */
            printf("\r\n\n External Reset");
        } else if(RESET != rcu_flag_get(RCU_FLAG_PORRST)) {
            printf("\r\n\n POR occurred....");
        }

        /* wait for RTC registers synchronization */
        rtc_register_sync_wait();

        /* enable the RTC second */
        rtc_interrupt_enable(RTC_INT_SECOND);

        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
    }

#ifdef RTCCLOCKOUTPUT_ENABLE
    /* enable PMU and BKPI clocks */
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);
    /* allow access to BKP domain */
    pmu_backup_write_enable();

    /* disable the tamper pin */
    bkp_tamper_detection_disable();

    /* enable RTC clock output on tamper Pin */
    bkp_rtc_calibration_output_enable();
#endif

    /* clear reset flags */
    rcu_all_reset_flag_clear();

    /* display time in infinite loop */
    time_show();

    while(1) {
    }
}

V2.9.0:
uint32_t RTCSRC_FLAG = 0;

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* COM1 config */
    gd_eval_com_init(EVAL_COM1);

    /* NVIC config */
    nvic_configuration();

    /* enable PMU and BKPI clocks */
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);

    /* allow access to BKP domain */
    pmu_backup_write_enable();
    if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)) {
        rcu_bkp_reset_disable();
    }

    /* get RTC clock entry selection */
    RTCSRC_FLAG = GET_BITS(RCU_BDCTL, 8, 9);

    printf("\r\n This is a RTC demo...... \r\n");

    if(0xA5A5 != bkp_data_read(BKP_DATA_0) || (0x00 == RTCSRC_FLAG)) {
        /* backup data register value is not correct or not yet programmed
        (when the first time the program is executed) */
        printf("\r\nThis is a RTC demo!\r\n");
        printf("\r\n\n RTC not yet configured....");

        /* RTC configuration */
        rtc_config();

        /* adjust time by values entred by the user on the hyperterminal */
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
        /* change the current time */
        rtc_counter_set(time_regulate());
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();

        bkp_data_write(BKP_DATA_0, 0xA5A5);
    } else {
        /* check if the power on reset flag is set */
        if(RESET != rcu_flag_get(RCU_FLAG_SWRST)) {
            /* check if the pin reset flag is set */
            printf("\r\n\n External Reset");
        } else if(RESET != rcu_flag_get(RCU_FLAG_PORRST)) {
            printf("\r\n\n POR occurred....");
        }

        /* wait for RTC registers synchronization */
        rtc_register_sync_wait();

        /* enable the RTC second */
        rtc_interrupt_enable(RTC_INT_SECOND);

        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
    }

#ifdef RTCCLOCKOUTPUT_ENABLE
    /* enable PMU and BKPI clocks */
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);
    /* allow access to BKP domain */
    pmu_backup_write_enable();

    /* disable the tamper pin */
    bkp_tamper_detection_disable();

    /* enable RTC clock output on tamper Pin */
    bkp_rtc_calibration_output_enable();
#endif

    /* clear reset flags */
    rcu_all_reset_flag_clear();

    /* display time in infinite loop */
    time_show();

    while(1) {
    }
}




__________________________________________________________________________________________________________________________

______________________SDIO________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________SYSTICK_____________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________SPI_________________________________________________________________________________________________

___________________________________________________________________________

______________________TIMER_______________________________________________________________________________________________

__________________________________________________________________________________________________________________________

______________________TLI_________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________TRNG________________________________________________________________________________________________


__________________________________________________________________________________________________________________________

______________________USART_______________________________________________________________________________________________
Fix file:
/GD32F20x_Firmware_Library/Examples/USART/Half_duplex_transmitter&receiver/main.c
fix reason: 
TX pin need be modified from open-drain output mode to open-drain mode
V2.8.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* enable USART and GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_USART1);

    /* configure USART0 Tx as alternate function push-pull */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* configure USART1 Tx as alternate function push-pull */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* USART0 and USART1 baudrate configuration */
    usart_baudrate_set(USART0, 115200);
    usart_baudrate_set(USART1, 115200);

    /* enable USART0 half duplex mode */
    usart_halfduplex_enable(USART0);
    /* enable USART1 half duplex mode */
    usart_halfduplex_enable(USART1);

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);

    /* enable USART */
    usart_enable(USART0);
    usart_enable(USART1);

    /* clear the USART1 data register */
    usart_data_receive(USART1);
    /* USART0 transmit and USART1 receive */
    while(transfersize0--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART0, transmitter_buffer0[txcount0++]);

        while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer1 */
        receiver_buffer1[rxcount0++] = usart_data_receive(USART1);
    }
    /* clear the USART0 data register */
    usart_data_receive(USART0);
    /* USART1 transmit and USART0 receive */
    while(transfersize1--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART1, transmitter_buffer1[txcount1++]);

        while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer0 */
        receiver_buffer0[rxcount1++] = usart_data_receive(USART0);
    }

    /* compare the received data with the send ones */
    state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0);
    state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1);
    if(SUCCESS == state1) {
        /* if the data transmitted from USART0 and received by USART1 are the same */
        gd_eval_led_on(LED2);
    } else {
        /* if the data transmitted from USART0 and received by USART1 are not the same */
        gd_eval_led_off(LED2);
    }
    if(SUCCESS == state2) {
        /* if the data transmitted from USART1 and received by USART0 are the same */
        gd_eval_led_on(LED3);
    } else {
        /* if the data transmitted from USART1 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
    }
    while(1) {
    }
}
V2.9.0:
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);

    /* enable USART and GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_USART1);

    /* configure USART0 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* configure USART1 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* USART0 and USART1 baudrate configuration */
    usart_baudrate_set(USART0, 115200);
    usart_baudrate_set(USART1, 115200);

    /* enable USART0 half duplex mode */
    usart_halfduplex_enable(USART0);
    /* enable USART1 half duplex mode */
    usart_halfduplex_enable(USART1);

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);

    /* enable USART */
    usart_enable(USART0);
    usart_enable(USART1);

    /* clear the USART1 data register */
    usart_data_receive(USART1);
    /* USART0 transmit and USART1 receive */
    while(transfersize0--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART0, transmitter_buffer0[txcount0++]);

        while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer1 */
        receiver_buffer1[rxcount0++] = usart_data_receive(USART1);
    }
    /* clear the USART0 data register */
    usart_data_receive(USART0);
    /* USART1 transmit and USART0 receive */
    while(transfersize1--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART1, transmitter_buffer1[txcount1++]);

        while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer0 */
        receiver_buffer0[rxcount1++] = usart_data_receive(USART0);
    }

    /* compare the received data with the send ones */
    state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0);
    state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1);
    if(SUCCESS == state1) {
        /* if the data transmitted from USART0 and received by USART1 are the same */
        gd_eval_led_on(LED2);
    } else {
        /* if the data transmitted from USART0 and received by USART1 are not the same */
        gd_eval_led_off(LED2);
    }
    if(SUCCESS == state2) {
        /* if the data transmitted from USART1 and received by USART0 are the same */
        gd_eval_led_on(LED3);
    } else {
        /* if the data transmitted from USART1 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
    }
    while(1) {
    }
}

__________________________________________________________________________________________________________________________

______________________USBFS_______________________________________________________________________________________________
Fix file:
../Firmware/GD32F20x_usbfs_library/host/core/Source/usbh_core.c
fix reason: 
Fix the issue where the enum_speed parameter may cause an array out-of-bounds error.
V2.8.0:
/*!
    \brief      active the USB endpoint0 transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB endpoint0 transaction
    \param[out] none
    \retval     operation status
*/
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;

    uint32_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES;

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    if(ep_num) {
        /* not endpoint 0 */
        return USB_FAIL;
    }

    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[0]->DIEPCTL;
    } else {
        reg_addr = &udev->regs.er_out[0]->DOEPCTL;
    }

    /* endpoint 0 is activated after USB clock is enabled */
    *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

    /* set endpoint 0 maximum packet length */
    *reg_addr |= EP0_MAXLEN[enum_speed];

    /* activate endpoint */
    *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;

    return USB_OK;
}

V2.9.0:
/*!
    \brief      active the USB endpoint0 transaction
    \param[in]  udev: pointer to USB device
    \param[in]  transc: the USB endpoint0 transaction
    \param[out] none
    \retval     operation status
*/
usb_status usb_transc0_active(usb_core_driver *udev, usb_transc *transc)
{
    __IO uint32_t *reg_addr = NULL;

    uint32_t enum_speed = ((udev->regs.dr->DSTAT & DSTAT_ES) >> 1);

    /* get the endpoint number */
    uint8_t ep_num = transc->ep_addr.num;

    if(ep_num) {
        /* not endpoint 0 */
        return USB_FAIL;
    }

    if(transc->ep_addr.dir) {
        reg_addr = &udev->regs.er_in[0]->DIEPCTL;
    } else {
        reg_addr = &udev->regs.er_out[0]->DOEPCTL;
    }

    /* endpoint 0 is activated after USB clock is enabled */
    *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM);

    /* set endpoint 0 maximum packet length */
    *reg_addr |= EP0_MAXLEN[enum_speed];

    /* activate endpoint */
    *reg_addr |= ((uint32_t)transc->ep_type << 18) | ((uint32_t)ep_num << 22) | DEPCTL_SD0PID | DEPCTL_EPACT;

    return USB_OK;
}
__________________________________________________________________________________________________________________________

______________________WWDGT_______________________________________________________________________________________________


__________________________________________________________________________________________________________________________


